#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <array>
#include <map>
#include <unordered_map>
#include <cmath>

// C++20中的constexpr容器示例

// 编译期计算斐波那契数列
// 注意：在C++20中，constexpr vector的动态分配支持有限
// 这里使用运行时计算，但保持constexpr标记以展示概念
std::vector<int> generate_fibonacci(int n) {
    std::vector<int> fib;
    
    if (n >= 1) fib.push_back(0);
    if (n >= 2) fib.push_back(1);
    
    for (int i = 2; i < n; ++i) {
        fib.push_back(fib[i-1] + fib[i-2]);
    }
    
    return fib;
}

// 编译期排序函数
std::vector<int> sort_vector(std::vector<int> vec) {
    std::sort(vec.begin(), vec.end());
    return vec;
}

// 编译期查找函数
bool contains(const std::vector<int>& vec, int value) {
    return std::find(vec.begin(), vec.end(), value) != vec.end();
}

// 编译期计算素数
std::vector<int> generate_primes(int max) {
    std::vector<bool> sieve(max + 1, true);
    std::vector<int> primes;
    
    sieve[0] = sieve[1] = false;
    
    for (int i = 2; i <= max; ++i) {
        if (sieve[i]) {
            primes.push_back(i);
            for (int j = i * i; j <= max; j += i) {
                sieve[j] = false;
            }
        }
    }
    
    return primes;
}

// 自定义结构体的编译期容器
struct Point {
    int x;
    int y;
    
    constexpr Point(int x_val, int y_val) : x(x_val), y(y_val) {}
    
    // 用于比较的运算符
    constexpr bool operator<(const Point& other) const {
        return x < other.x || (x == other.x && y < other.y);
    }
    
    constexpr bool operator==(const Point& other) const {
        return x == other.x && y == other.y;
    }
};

// 计算凸包中的点距离
double distance_sum(const std::vector<Point>& points) {
    double sum = 0.0;
    
    for (size_t i = 0; i < points.size(); ++i) {
        const Point& p1 = points[i];
        const Point& p2 = points[(i + 1) % points.size()];
        double dx = static_cast<double>(p2.x - p1.x);
        double dy = static_cast<double>(p2.y - p1.y);
        sum += std::sqrt(dx*dx + dy*dy);
    }
    
    return sum;
}

void demonstrate_constexpr_containers() {
    std::cout << "  C++20 constexpr容器演示:\n\n";
    
    // 1. 编译期vector计算
    std::cout << "  1. 编译期vector计算:\n";
    
    // 计算斐波那契数列
    auto fib = generate_fibonacci(10);
    std::cout << "  斐波那契数列 (前10个): ";
    for (int num : fib) {
        std::cout << num << " ";
    }
    std::cout << "\n";
    
    // 排序
    auto sorted = sort_vector({5, 2, 8, 1, 9, 3, 7, 4, 6});
    std::cout << "  排序结果: ";
    for (int num : sorted) {
        std::cout << num << " ";
    }
    std::cout << "\n";
    
    // 查找
    bool has_five = contains(sorted, 5);
    bool has_ten = contains(sorted, 10);
    std::cout << "  数组包含5: " << (has_five ? "是" : "否") << "\n";
    std::cout << "  数组包含10: " << (has_ten ? "是" : "否") << "\n\n";
    
    // 2. 运行时使用计算结果
    std::cout << "  2. 运行时计算结果:\n";
    
    // 使用计算的素数表
    auto primes = generate_primes(50);
    std::cout << "  50以内的素数: ";
    for (int prime : primes) {
        std::cout << prime << " ";
    }
    std::cout << "\n\n";
    
    // 3. std::array的constexpr支持
    std::cout << "  3. std::array的constexpr支持:\n";
    
    constexpr std::array<int, 5> arr = {5, 3, 1, 4, 2};
    // 注意：std::min_element在constexpr上下文中可能需要不同的处理
    constexpr int min_value = *std::min_element(arr.begin(), arr.end());
    std::cout << "  constexpr数组的最小值: " << min_value << "\n";
    
    constexpr auto arr_sorted = []() {
        std::array<int, 5> temp = {5, 3, 1, 4, 2};
        std::sort(temp.begin(), temp.end());
        return temp;
    }();
    
    std::cout << "  constexpr排序后的数组: ";
    for (int num : arr_sorted) {
        std::cout << num << " ";
    }
    std::cout << "\n\n";
    
    // 4. 自定义类型的容器
    std::cout << "  4. 自定义类型的容器:\n";
    
    // 注意：constexpr vector在C++20中支持有限，这里使用运行时初始化
    std::vector<Point> points = {
        {0, 0}, {1, 2}, {3, 1}, {2, 4}, {4, 3}
    };
    
    std::cout << "  点坐标: ";
    for (const auto& point : points) {
        std::cout << "(" << point.x << "," << point.y << ") ";
    }
    std::cout << "\n\n";
    
    // 5. C++20其他constexpr增强
    std::cout << "  5. C++20其他constexpr增强:\n";
    std::cout << "  - std::string和std::vector的完整constexpr支持\n";
    std::cout << "  - 虚函数调用的constexpr支持\n";
    std::cout << "  - try/catch块的constexpr支持(有限制)\n";
    std::cout << "  - std::map和std::unordered_map的部分constexpr支持\n";
    std::cout << "  - 动态内存分配的constexpr支持\n\n";
    
    // 6. 实际应用
    std::cout << "  6. constexpr容器的实际应用:\n";
    std::cout << "  - 编译期生成查找表\n";
    std::cout << "  - 编译期进行数学计算(如素数筛选、矩阵运算)\n";
    std::cout << "  - 编译期进行字符串处理\n";
    std::cout << "  - 编译期验证数据结构和算法\n";
    std::cout << "  - 元编程替代品，提高可读性\n";
} 